#include <head.h>

#define SIZE_BUF_MAX 1024

typedef struct str
{
    const char *desk_fd;
    const char *src_fd;

    off_t start;
    off_t end;
} str;

void *copy_file(void *str_1)
{
    str str_2 = *(str *)str_1;
    // 设定缓冲区
    int desk_fd_1 = open(str_2.desk_fd, O_WRONLY | O_CREAT | O_TRUNC, 0664); // 目标文件
    //OPEN_ERR(desk_fd_1);

    int src_fd_1 = open(str_2.src_fd, O_RDONLY); // 源文件
   // OPEN_ERR(src_fd_1);
    char buf[SIZE_BUF_MAX];
    // 设定文件起始位置
    lseek(desk_fd_1, str_2.start, SEEK_SET);
    lseek(src_fd_1, str_2.start, SEEK_SET);

    // 开始拷贝
    size_t byte_read = 0;
    size_t byte_write = 0;

    while (str_2.start < str_2.end)
    {
        if ((byte_read = read(src_fd_1, buf, SIZE_BUF_MAX)) <= 0)
        {
            break;
        }
        if ((byte_write = write(desk_fd_1, buf, byte_read)) <= 0)
        {
            break;
        }

        // 位置迭代
        str_2.start += byte_write;
    }
    close(src_fd_1);
    close(desk_fd_1);
}

int main(int argc, char const *argv[])
{

    // 安排判定
    if (3 != argc)
    {
        printf("格式错误 %s dest src\n", argv[0]);
        return 0;
    }

    // 打开文件
    int desk_fd_1 = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0664); // 目标文件
    OPEN_ERR(desk_fd_1);

    int src_fd_1 = open(argv[2], O_RDONLY); // 源文件
    OPEN_ERR(src_fd_1);

    // 获取文件状态
    struct stat file_stat; // 文件状态结构体

    if (fstat(src_fd_1, &file_stat) < 0)
    {
        perror("fstat err");
        close(desk_fd_1);
        close(src_fd_1);
        return 0;
    }

    fstat(src_fd_1, &file_stat); 
   
    // 获取文件大小 并计算每个进程 所拷贝的范围
    off_t file_size = file_stat.st_size; // 文件大小
    printf("%ld",file_size);
    off_t part_size = file_size / 2;

    str argv_t[2] = {{.desk_fd = argv[1], .src_fd = argv[2], .start = 0, .end = part_size},
                     {.desk_fd = argv[1], .src_fd = argv[2], .start = part_size, .end = file_size}};
    pthread_t tid_1 = 0;
    pthread_t tid_2 = 0;

    // 创建线程
    pthread_create(&tid_1, NULL, copy_file, (void *)&argv_t[0]);
    pthread_create(&tid_2, NULL, copy_file, (void *)&argv_t[1]);

    // 回收线程
    pthread_join(tid_1, NULL);
    pthread_join(tid_2, NULL);

    close(src_fd_1);
    close(desk_fd_1);
    return 0;
}
